import { ArrayUtils, FileUtils, YamlUtils } from "../utils";
import { esi } from "../repositories";

import {
  YAMLBlueprintsSchema,
  YAMLPlanetSchematicsSchema,
  YAMLTypeMaterialsSchema,
  YAMLUniverseTypeSchema,
} from "./types";
import {
  FORMATED_BLUEPRINTS_FILE,
  FORMATED_CATEGORY_FILE,
  FORMATED_PLANET_SCHEMATICS_FILE,
  FORMATED_TYPE_FILE,
  FORMATED_TYPE_MATERIALS_FILE,
  SDE_BLUEPRINTS_FILE,
  SDE_PLANET_SCHEMATICS_FILE,
  SDE_TYPE_FILE,
  SDE_TYPE_MATERIALS_FILE,
} from "./contanst";
import { BluePrint, PlanetSchematics, UniverseCategory, UniverseGroup, UniverseType } from "./entity";
import type { LoadingControl } from "./utils/SDEFileUtils";
import type {
  YAMLPlanetSchematicsMap,
  YAMLTypeMaterialsMap,
  YAMLUniverseTypeMap,
  YAMLYAMLBlueprintsMap,
} from "./types";

const alias: Record<string, string> = {
  工业炸药: "工业爆炸物",
  透颅微控器: "颅腔穿透型微型控制器",
};

export const reformatTypeMaterials = (types: Map<number, UniverseType>) => {
  const materialsMap = YamlUtils.read<YAMLTypeMaterialsMap>(SDE_TYPE_MATERIALS_FILE, YAMLTypeMaterialsSchema);
  FileUtils.writeJSON(
    FORMATED_TYPE_MATERIALS_FILE,
    Object.entries(materialsMap).map(([key, value]) => {
      const id = Number.parseInt(key);
      return {
        id,
        name: types.get(id)!.name,
        materials: value.materials.map((item) => ({
          id: item.materialTypeID,
          name: types.get(item.materialTypeID)!.name,
          quantity: item.quantity,
        })),
      };
    })
  );
};
export const reformatTypes = async (loading?: LoadingControl) => {
  const records = Object.entries(YamlUtils.read<YAMLUniverseTypeMap>(SDE_TYPE_FILE, YAMLUniverseTypeSchema));
  const types = records
    .map(([id, type]) => {
      return UniverseType.fromYaml(Number(id), type);
    })
    .filter((item) => item.name);
  const fullTypeIds = new Set(await esi.universe.types());
  const normalIds = new Set(types.map((t) => t.id));
  const extTypes: UniverseType[] = [];
  for (const id of fullTypeIds) {
    if (normalIds.has(id)) continue;
    const type = await esi.universe.type(id);
    if (!type) throw new Error(`${id} esi search fail`);
    if (loading) {
      loading.setText(`正在同步 ${type.name}`);
    }
    extTypes.push(
      UniverseType.fromYaml(type.type_id, {
        groupID: type.group_id,
        iconID: type.icon_id,
        marketGroupID: type.market_group_id,
        mass: type.mass,
        metaGroupID: type.market_group_id,
        name: { zh: type.name },
        portionSize: type.portion_size,
        published: type.published,
        radius: type.radius,
        volume: type.volume,
      })
    );
  }
  if (extTypes.length > 0) {
    types.push(...extTypes);
  }
  FileUtils.writeJSON(FORMATED_TYPE_FILE, types);
  return types;
};

export const reformatBluePrints = (types: Map<number, UniverseType>) => {
  const blueprints = YamlUtils.read<YAMLYAMLBlueprintsMap>(SDE_BLUEPRINTS_FILE, YAMLBlueprintsSchema);
  const formatedBlueprints = Object.entries(blueprints).map(([, value]) => BluePrint.fromYaml(value, types));
  FileUtils.writeJSON(FORMATED_BLUEPRINTS_FILE, formatedBlueprints);
};
export const reformatPlanetSchematics = (types: Map<number, UniverseType>) => {
  const nameMap = ArrayUtils.toMap(Array.from(types.values()), (e) => e.name);
  Object.entries(alias).forEach(([key, value]) => {
    nameMap.set(value, nameMap.get(key)!);
  });
  const planetSchematics = YamlUtils.read<YAMLPlanetSchematicsMap>(
    SDE_PLANET_SCHEMATICS_FILE,
    YAMLPlanetSchematicsSchema
  );
  FileUtils.writeJSON(
    FORMATED_PLANET_SCHEMATICS_FILE,
    Object.entries(planetSchematics).map(([, value]) => {
      return PlanetSchematics.fromYaml(value, types, nameMap);
    })
  );
};

export const reformatCategory = async (loading?: LoadingControl) => {
  const categoryIds = await esi.universe.categories();
  const categories: UniverseCategory[] = [];
  for (const categoryId of categoryIds!) {
    const category = (await esi.universe.category(categoryId))!;
    loading?.setText(`正在同步物品大类 ${category.name}`);
    categories.push(UniverseCategory.fromCategory(category));
  }
  const groupIds = await esi.universe.groups();
  for (const groupId of groupIds!) {
    const group = (await esi.universe.group(groupId))!;
    loading?.setText(`正在同步物品分类 ${group.name}`);
    const category = categories.find((c) => c.id === group.category_id)!;
    UniverseGroup.fromGroup(group, category);
  }
  FileUtils.writeJSON(FORMATED_CATEGORY_FILE, categories);
};
